<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="TX40z" id="TX40z"><span data-lake-id="uff29ae3d" id="uff29ae3d">典型回答</span></h1>
  <p data-lake-id="u999506d3" id="u999506d3"><span data-lake-id="u4251bfe3" id="u4251bfe3">在回答这个问题之前，我们先看一段用JDBC和Mybatis写的代码：</span></p>
  <pre lang="java"><code>
public void testJdbc() {
    String url = "dbLink";
    try(Connection conn = DriverManager.getConnection(url, "root", "password")){
        // 加载MySQL驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        int author = 1;
        String date = "2018.06.10";
        String sql = "SELECT id, title, content, create_time FROM article WHERE author_id = " + author
                + " AND create_time &gt; '" + date + "'";
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        List&lt;Article&gt; articles = new ArrayList&lt;&gt;(rs.getRow());
        while (rs.next()) {
            Article article = new Article();
            article.setId(rs.getInt("id"));
            article.setTitle(rs.getString("title"));
            article.setContent(rs.getString("content"));
            article.setCreateTime(rs.getDate("create_time"));
            articles.add(article);
        }
        System.out.println("Query SQL ==&gt; " + sql);
        System.out.println("Query Result: ");
        articles.forEach(System.out::println);
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    }
}
</code></pre>
  <pre lang="java"><code>
public void testMyBatis() throws IOException {
	String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new
            SqlSessionFactoryBuilder().build(inputStream);
    inputStream.close();
    try(SqlSession session = sqlSessionFactory.openSession()) {
        ArticleDao articleDao = session.getMapper(ArticleDao.class);
        List&lt;Article&gt; articles = articleDao.
                findByAuthorAndCreateTime(1, "2018-06-10");
        System.out.println(articles);
    }
}
inteface ArticleDao {
    @Query({"SELECT id, title, content, create_time FROM article WHERE author_id = #{id} AND create_time &gt; #{time}"})
	List&lt;Article&gt; findByAuthorAndCreateTime(int id, String time);
}
</code></pre>
  <p data-lake-id="u8b42047f" id="u8b42047f"><span data-lake-id="ucd204cf9" id="ucd204cf9">很明显，我们能看到使用Mybatis的代码，结构更清晰，代码量也比较少，这就是Mybatis最直观的优点：</span></p>
  <ol list="uf7e595a7">
   <li fid="ubd2e0288" data-lake-id="u0beac95b" id="u0beac95b"><span data-lake-id="u0bae9852" id="u0bae9852">将数据库的操作逻辑和业务操作</span><strong><span data-lake-id="u17da7f39" id="u17da7f39">解耦合</span></strong><span data-lake-id="u522812b6" id="u522812b6">，使得开发人员可以专心业务逻辑的处理。</span></li>
   <li fid="ubd2e0288" data-lake-id="u56a2d79b" id="u56a2d79b"><span data-lake-id="u00644b86" id="u00644b86">开发人员只写Sql就可以访问数据库，</span><strong><span data-lake-id="u627a71ca" id="u627a71ca">不需要关心各种数据库连接等额外的操作</span></strong><span data-lake-id="u2bf37850" id="u2bf37850">。各种Connection和Statement都交给了Mybatis来管理</span></li>
   <li fid="ubd2e0288" data-lake-id="u25241453" id="u25241453"><span data-lake-id="uea82f61f" id="uea82f61f">可以</span><strong><span data-lake-id="u617c1725" id="u617c1725">将数据库表的字段按照业务规则直接映射到DO层</span></strong><span data-lake-id="ucd706bcb" id="ucd706bcb">，不用再像JDBC一样需要业务代码来转换</span></li>
  </ol>
  <p data-lake-id="udd2b38e9" id="udd2b38e9"><span data-lake-id="ua665dcdb" id="ua665dcdb">除此之外，还有其他优点：</span></p>
  <ol list="uf7e595a7" start="4">
   <li fid="ubd2e0288" data-lake-id="u196c1c5e" id="u196c1c5e"><strong><span data-lake-id="ub95b0248" id="ub95b0248">支持多种数据源</span></strong><span data-lake-id="u81bf3a4f" id="u81bf3a4f">，如POOLED，UNPOOLED，JNDI。同时，还可以整合其他数据库连接池如HikariCP，Druid，C3p0等</span></li>
   <li fid="ubd2e0288" data-lake-id="u63d6275d" id="u63d6275d"><strong><span data-lake-id="u7f94c5b0" id="u7f94c5b0">支持动态SQL</span></strong><span data-lake-id="u198b37b0" id="u198b37b0">，大大减少了代码的开发量，如if/foreach等常用的动态标签</span></li>
   <li fid="ubd2e0288" data-lake-id="u2486234b" id="u2486234b"><strong><span data-lake-id="uc3c74a33" id="uc3c74a33">支持事务性的一级缓存，二级缓存和自定义缓存</span></strong><span data-lake-id="u00a450db" id="u00a450db">，其中，一级缓存是以session为生命周期，默认开启；二级缓存则是根据配置的算法来计算过期时间（FIFO，LRU等），二级缓存如果操作不当容易产生脏数据，不建议使用</span></li>
  </ol>
 </body>
</html>